home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 2 / Amiga Tools 2.iso / tools / packer / tar / src / utime.c < prev    next >
C/C++ Source or Header  |  1995-03-09  |  5KB  |  176 lines

  1. /*
  2.  * TITLE: touch.c This is a simple command to set the date of a file to
  3.  * now. It was compiled using Greenhills C.  You might have to change it a
  4.  * little for use with Lattice or Manx. The program compiles with just
  5.  * amigalib.  (that's why those string functions are tacked on the end of
  6.  * the file)
  7.  */
  8.  
  9. /*
  10.  * Changed to be utime function by Jonathan Hue
  11.  */
  12.  
  13. /* touch.c by Phil Lindsay and Andy Finkel              */
  14. /* (c) 1986 Commodore-Amiga, Inc.                       */
  15. /* Permission to use in any way granted, as long as     */
  16. /* the copyright notice stays intact                    */
  17.  
  18. #include "exec/types.h"
  19. #include "exec/ports.h"
  20. #include "exec/io.h"
  21. #include "exec/memory.h"
  22. #include "libraries/dos.h"
  23. #include "libraries/dosextens.h"
  24. #include <sys/types.h>
  25. #include <errno.h>
  26.  
  27. extern LONG sendpkt();
  28.  
  29. #define ACTION_SET_DATE     34
  30.  
  31. static struct DateStamp *seconds2AmiTime();
  32.  
  33. int
  34. utime(char *filename, time_t unixtime[2])
  35. {
  36.     struct DateStamp dateStamp;
  37.  
  38.     return(utime_from_stamp(filename, seconds2AmiTime(unixtime[1]),
  39.                 &dateStamp));
  40. }
  41.  
  42. int
  43. utime_from_stamp(char *filename, struct DateStamp *ds)
  44. {
  45.     struct MsgPort *task;
  46.     struct FileInfoBlock *fib;
  47.     LONG arg[4];
  48.     LONG rc;
  49.     ULONG lock;
  50.     ULONG plock;
  51.     UBYTE *pointer;
  52.  
  53.     pointer = NULL;
  54.     if (!(pointer = (UBYTE *) AllocMem(64, MEMF_PUBLIC)))
  55.     {
  56.     errno = ENOMEM;
  57.     return(-1);
  58.     }
  59.     if (!(task = (struct MsgPort *) DeviceProc(filename)))
  60.     {
  61.     FreeMem(pointer, 64);
  62.     errno = ENOENT;
  63.     return(-1);
  64.     }
  65.     if (!(lock = (ULONG) Lock(filename, SHARED_LOCK)))
  66.     {
  67.     FreeMem(pointer, 64);
  68.     errno = ENOENT;
  69.     return(-1);
  70.     }
  71.     plock = (ULONG) ParentDir(lock);
  72.     if (!plock)            /* filename is root dir, can't set time */
  73.     {
  74.     FreeMem(pointer, 64);    /* sometimes you almost want to use a goto */
  75.     errno = EACCES;
  76.     UnLock(lock);
  77.     return(-1);
  78.     }
  79.     if (!(fib = malloc(sizeof(*fib))))
  80.     {
  81.     FreeMem(pointer, 64);
  82.     errno = ENOMEM;
  83.     UnLock(lock);
  84.     return(-1);
  85.     }
  86.     Examine(lock, fib);
  87.     UnLock(lock);
  88.     strcpy((pointer + 1), fib->fib_FileName);
  89.     *pointer = strlen(fib->fib_FileName);
  90.     free(fib);
  91.     arg[0] = NULL;
  92.     arg[1] = plock;
  93.     arg[2] = (ULONG) & pointer[0] >> 2;    /* BSTR of filename */
  94.     arg[3] = (ULONG) ds;        /* DateStamp */
  95.     rc = sendpkt(task, ACTION_SET_DATE, arg, 4);
  96.  
  97.     UnLock(plock);
  98.     FreeMem(pointer, 64);
  99.     return (0);
  100. }
  101.  
  102.  
  103. LONG
  104. sendpkt(id, type, args, nargs)
  105. struct MsgPort *id;/* process indentifier ... (handlers message port ) */
  106. LONG type;       /* packet type ... (what you want handler to do )   */
  107. LONG args[];            /* a pointer to a argument list */
  108. LONG nargs;                /* number of arguments in list  */
  109. {
  110.  
  111.     struct MsgPort *replyport;
  112.     struct StandardPacket *packet = NULL;
  113.     LONG count;
  114.     LONG *pargs;
  115.     LONG res1 = NULL;
  116.  
  117.  
  118.     if (!(replyport = (struct MsgPort *) CreatePort(NULL, NULL)))
  119.     return (NULL);
  120.  
  121.     packet = (struct StandardPacket *)
  122.     AllocMem((LONG) sizeof(*packet), MEMF_PUBLIC | MEMF_CLEAR);
  123.  
  124.     if (packet)
  125.     {
  126.     packet->sp_Msg.mn_Node.ln_Name = (char *) &(packet->sp_Pkt);    /* link packet */
  127.     packet->sp_Pkt.dp_Link = &(packet->sp_Msg);    /* to message    */
  128.     packet->sp_Pkt.dp_Port = replyport;    /* set-up reply port   */
  129.     packet->sp_Pkt.dp_Type = type;    /* what to do... */
  130.  
  131.     /* move all the arguments to the packet */
  132.     pargs = &(packet->sp_Pkt.dp_Arg1);    /* address of first
  133.                          * argument */
  134.     for (count = 0; (count < nargs) && (count < 7); count++)
  135.         pargs[count] = args[count];
  136.  
  137.     PutMsg(id, packet);    /* send packet */
  138.     WaitPort(replyport);    /* wait for packet to come back */
  139.     GetMsg(replyport);    /* pull message */
  140.  
  141.     res1 = packet->sp_Pkt.dp_Res1;    /* get result */
  142.         FreeMem(packet, (LONG) sizeof(*packet));
  143.  
  144.     }
  145.     DeletePort(replyport);
  146.     return (res1);
  147. }
  148.  
  149. /*
  150.  * Convert seconds into Amiga style time (days since 1/1/78, minutes since
  151.  * 12AM, ticks this hour)
  152.  */
  153. static struct DateStamp *
  154. seconds2AmiTime(long secs, struct DateStamp *ds)
  155. {
  156.     extern long timezone;
  157.  
  158.     /* seconds is in GMT, so compensate */
  159.     secs -= timezone;
  160.  
  161.     /* Subtract 8 years worth of seconds, including 2 leap years */
  162.     secs -= ((6 * 365) + (2 * 366)) * (60 * 60 * 24);
  163.  
  164.     /* Now have seconds since 1/1/78, get days */
  165.     ds->ds_Days = secs / (60 * 60 * 24);
  166.     secs -= ds->ds_Days * (60 * 60 * 24);
  167.  
  168.     /* Now have seconds since midnight, get minutes */
  169.     ds->ds_Minute = secs / 60;
  170.     secs -= ds->ds_Minute * 60;
  171.  
  172.     /* Now have seconds this minute, convert to ticks */
  173.     ds->ds_Tick = secs * 50;
  174.     return(ds);
  175. }
  176.